//JavaScript
//基于后台配置规则验证表单，通过配置实现前台验证和后台验证的统一

var FormVerifier = {
	path: UiUtil.path,
	parseJSON: function(data){
		return new Function("return " + data)();
	},
	getJsonValue: function(data, name){
		if(!!data && !!name){
			if(name.indexOf('[') == 0 || name.indexOf('.') == 0){
				try{
					return new Function("data", "return data" + name + ";" )(data);
				}catch(e){}
			}else if(name.indexOf('[') != -1 || name.indexOf('.') != -1){
				try{
					return new Function("data", "return data." + name + ";" )(data);
				}catch(e){}
			}else{
				return data[name];
			}
		}
		return null;
	},
	getFormAction: function(formID){
		var ac = $('#'+formID).attr('action');
		if(ac){
			if((/^http:\/\//i).test(ac)){
				ac = ac.substring(7);
				ac = ac.substring(ac.indexOf('/'));
			}else if((/^https:\/\//i).test(ac)){
				ac = ac.substring(8);
				ac = ac.substring(ac.indexOf('/'));
			}
			var cpath = FormVerifier.path;
			if((/^http:\/\//i).test(cpath)){
				cpath = cpath.substring(7);
				if(cpath.indexOf('/') != -1){
					cpath = cpath.substring(cpath.indexOf('/'));
				}else{
					cpath = '';
				}
			}else if((/^https:\/\//i).test(cpath)){
				cpath = cpath.substring(8);
				if(cpath.indexOf('/') != -1){
					cpath = cpath.substring(cpath.indexOf('/'));
				}else{
					cpath = '';
				}
			}
			ac = ac.substring(cpath.length);
			if(ac.indexOf('?')!=-1){
				ac = ac.substring(0, ac.indexOf('?'));
			}
		}
		return ac;
	},
	getAjaxValidatorSetting: function(rule){
		var opts = {url: FormVerifier.path+rule.url, type: "GET", dataType: "text", async: true, _vrule: rule};
		if(rule.type){
			opts.type = rule.type;
		}
		if(rule.dataType){
			opts.dataType = rule.dataType;
		}
		if(rule.async !== undefined && rule.async !== null){
			opts.async = rule.async;
		}
		if(rule.error){
			opts.onError = rule.error;
		}
		if(rule.params){
			var data = {};
			var arr = rule.params.split(/[,;]/g);
			for(var k=0; k<arr.length; k++){
				var paramname = arr[k];
				if(!paramname)continue;
				var paramvalue = paramname;
				if(paramname.indexOf('=') != -1){
					var arr = paramname.split('=');
					paramname = arr[0];
					paramvalue = arr[1];
				}
				var fn = function(){
					var _paramvalue = arguments.callee.paramvalue;
					var val = $('#'+_paramvalue).val();
					if(val !== undefined && val !== null){
						return val;
					}
					val = $(":input[name='"+_paramvalue+"']").val();
					if(val !== undefined && val !== null){
						return val;
					}
					return $("[name='"+_paramvalue+"']:checked").val() || '';
				};
				fn.paramvalue = paramvalue;
				data[paramname] = fn;
			}
			opts.data = data;
		}
		opts.success = function(data){
			var rule = this._vrule, dataType = this.dataType;
			if(dataType == 'text'){
				rule.okcode = rule.okcode || "0";
				rule.errcode = rule.errcode || "1";
				if(data == rule.okcode){
					return true;
				}else if(data == rule.errcode){
					return false;
				}else{
					return data;
				}
			}else{
				if(typeof(data)=='string'){
					data = FormVerifier.parseJSON(data);
				}
				rule.okcode = rule.okcode || "";
				rule.errcode = rule.errcode || "";
				var okArr = rule.okcode.split("=");
				var errArr = rule.errcode.split("=");
				if((''+FormVerifier.getJsonValue(data, okArr[0])) == okArr[1]){
					return true;
				}else if((''+FormVerifier.getJsonValue(data, errArr[0])) == errArr[1]){
					return false;
				}else{
					var msg = FormVerifier.getJsonValue(data, errArr[0]);
					msg = FormVerifier.getJsonValue(data, msg);
					return msg || false;
				}
			}
		};
		return opts;
	},
	getNumRangeSetting: function(rule){
		var opts = {_vrule: rule, parseFn: parseInt}, exprs = rule.exprs;
		if(rule.error){
			opts.onError = rule.error;
		}
		for(var i=0; i<exprs.length; i++){
			if(exprs[i].indexOf('.') != -1){
				opts.parseFn = parseFloat;
				break;
			}
		}
		opts.fun = function(val){
			var rule = this._vrule, exprs = rule.exprs, type = rule.type, compare = rule.compare, parseFn = this.parseFn, pass = false, maxvalue, minvalue;
			if(type == 'length'){
				val = val.length;
				maxvalue = 2147483647;
				minvalue = 0;
			}else{
				val = parseFn(val);
				maxvalue = Number.MAX_VALUE;
				minvalue = -1 * Number.MAX_VALUE;
			}
			for(var i=0; i<exprs.length; i++){
				var expr = exprs[i], valid = false, rs;
				if((/^-?\d+(\.\d+)?$/).test(expr)){
					valid = (val == parseFn(expr));
				}else if((rs = (/^(-?\d+(\.\d+)?|MIN)(([-~]{2})|%)(-?\d+(\.\d+)?|MAX)$/).exec(expr)) != null){
					var v1 = rs[1];
					var op = rs[3];
					var v2 = rs[5];
					if("MIN" == v1){
						v1 = minvalue;
					}else{
						v1 = parseFn(v1);
					}
					if("MAX" == v2){
						v2 = maxvalue;
					}else{
						v2 = parseFn(v2);
					}
					if("%" == op){
						valid = (val % v2 == v1);
					}else if("--" == op){
						valid = (v1 <= val && v2 >= val);
					}else if("~~" == op){
						valid = (v1 < val && v2 > val);
					}else if("-~" == op){
						valid = (v1 <= val && v2 > val);
					}else if("~-" == op){
						valid = (v1 < val && v2 >= val);
					}
				}
				if(compare == "or" && valid){
					pass = true;
					break;
				}
				if(compare == "and" && !valid){
					break;
				}
			}
			return pass;
		};
		return opts;
	},
	
	doVerify: function(data, settings){
		var vmap = {}, items = data.items || [];
		for(var i=0; i<items.length; i++){
			var itm = items[i], itmopts, obj;
			if(typeof itm.settings == 'string'){
				itmopts = FormVerifier.parseJSON(itm.settings || "{}");
			}else{
				itmopts = itm.settings || {};
			}
			itmopts = $.extend({}, settings.item_settings || {}, itmopts);
			if(itm.tips){
				itmopts.onFocus = itm.tips;
			}
			if(itm.empty){
				itmopts.empty = itm.empty;
			}
			if(itm.check === true){
				obj = $("[name='"+(itm.name||itm.id)+"']");
				if(!itmopts.tipID){
					itmopts.tipID = (itm.name||itm.id)+"Tip";
				}
			}else{
				obj = $("#"+itm.id);
			}
			obj.formValidator(itmopts);
			var rules = itm.rules;
			for(var j=0; j<rules.length; j++){
				var rule = rules[j], ruletype = rule.rtype;
				if(ruletype == "input"){
					var opts = {type : "size"};
					if(rule.type){
						if(rule.type == "checked" || rule.type == "selected"){
							rule.type == "size";
						}
						opts.type = rule.type;
					}
					if(rule.min !== undefined && rule.min !== null){
						opts.min = rule.min;
					}
					if(rule.max !== undefined && rule.max !== null){
						opts.max = rule.max;
					}
					if(rule.error){
						opts.onError = rule.error;
					}
					obj.inputValidator(opts);
					
				}else if(ruletype == "regexp"){
					var opts = {regExp: rule.regexps, compareType : "||", param: "i"};
					if(rule.compare=="or"){
						opts.compareType = "||";
					}else if(rule.compare=="and"){
						opts.compareType = "&&";
					}
					if(rule.ignoreCase === false){
						opts.param = "";
					}
					if(rule.error){
						opts.onError = rule.error;
					}
					obj.regexValidator(opts);
					
				}else if(ruletype == "compare"){
					var opts = {desID: rule.dest, dataType: "string", operateor :"="};
					if(rule.type){
						opts.dataType = rule.type;
					}
					if(rule.operateor){
						switch(rule.operateor)
					    {
					    case "eq": opts.operateor = "="; break;
					    case "ne": opts.operateor = "!="; break;
					    case "gt": opts.operateor = ">"; break;
					    case "ge": opts.operateor = ">="; break;
					    case "lt": opts.operateor = "<"; break;
					    case "le": opts.operateor = "<="; break;
					    }
					}
					if(rule.error){
						opts.onError = rule.error;
					}
					obj.compareValidator(opts);
					
				}else if(ruletype == "ajax"){
					obj.ajaxValidator(FormVerifier.getAjaxValidatorSetting(rule));
					
				}else if(ruletype == "combox"){
					var opts = {_vrule: rule};
					if(rule.error){
						opts.onError = rule.error;
					}
					opts.fun = function(val, obj){
						return $('#'+this._vrule.valueid).val().length>0;
					};
					obj.functionValidator(opts);
					
				}else if(ruletype == "numrange"){
					obj.functionValidator(FormVerifier.getNumRangeSetting(rule));
					
				}else if(ruletype == "anyitem"){
					var opts = {_vrule: rule};
					if(rule.error){
						opts.onError = rule.error;
					}
					opts.fun = function(val, obj){
						var num = 0, thispass, varr=[];
						if(val && (/^[\s\S]*[^\s\u3000]+[\s\S]*$/).test(val)){
							num++;
							thispass = true;
						}
						var dest = this._vrule.dest || [];
						$.each(dest, function(i2, id2){
							val = $('#'+id2).val();
							if(val && (/^[\s\S]*[^\s\u3000]+[\s\S]*$/).test(val)){
								num++;
								varr.push(true);
							}else{
								varr.push(false);
							}
						});
						if(!$(obj).data('fvpassblur')){
							$.each(dest, function(i2, id2){
								if(!varr[i2]){
									$('#'+id2).data('fvpassblur', true).focus().blur();
								}
							});
						}else{
							$(obj).removeData('fvpassblur');
						}
						return (num >= this._vrule.min) || !!thispass;
					};
					obj.functionValidator(opts);
				}
			}
			vmap[itm.id] = true;
		}
		return vmap;
	},
	
	_startsWith: function(str, prefix){
		for(var i=0, n=prefix.length; i<n; i++){
			if(str.charAt(i) != prefix.charAt(i)) {
				return false;
			}
		}
		return true;
	},
	_setRegexpRuleArgs: function(rule, args){
		if(!args)return;
		for(var i=0; i<args.length; i++){
			var c = args.charAt(i);
			if(c == 'a'){
				rule.compare = 'and';
			}else if(c == 'o'){
				rule.compare = 'or';
			}else if(c == 'I'){
				rule.ignoreCase = false;
			}else if(c == 'i'){
				rule.ignoreCase = true;
			}
		}
	},
	parseRulesExpr: function(regData, items){
		for(var i=0; i<items.length; i++){
			var item = items[i], rulesExpr = item.expr;
			if(!item.rules){
				item.rules = [];
			}
			if(!rulesExpr){
				continue;
			}
			var exprrules = [];
			for(var j=0; j<rulesExpr.length; j++){
				var expr = rulesExpr[j], rs;
				if(FormVerifier._startsWith(expr, 'required') && (rs=(/^required(:(\w+)?)?(\{(.+)\})?$/).exec(expr)) != null){
					var rule = {rtype:'regexp', ignoreCase: true, regexps:[]};
					FormVerifier._setRegexpRuleArgs(rule, rs[2]);
					rule.compare = 'or';
					rule.regexps.push("^[\\s\\S]*[^\\s\u3000]+[\\s\\S]*$");
					rule.error = rs[4] || "不能为空.";
					exprrules.push(rule);
					
				}else if(FormVerifier._startsWith(expr, 'reg') && (rs=(/^reg(:(\w+)?)?\[(.+)\](\{(.+)\})?$/).exec(expr)) != null){
					var rule = {rtype:'regexp', ignoreCase: true, regexps:[]};
					FormVerifier._setRegexpRuleArgs(rule, rs[2]);
					rule.compare = 'or';
					rule.regexps.push(rs[3]);
					rule.error = rs[5] || "输入格式错误.";
					exprrules.push(rule);
					
				}else if(FormVerifier._startsWith(expr, 'ajax') && (rs=(/^ajax(:(\w+)?)?\[(.+?)(,(.*?))?(,(.*?))?(,(.+))?\](\{(.+)\})?$/).exec(expr)) != null){
					var rule = {rtype:'ajax', type: 'GET', dataType: 'text', async:true, okcode:'0', errcode:'1'}, args = rs[2];
					if(args){
						for(var i=0; i<args.length; i++){
							var c = args.charAt(i);
							if(c == 'g'){
								rule.type = 'GET';
							}else if(c == 'p'){
								rule.type = 'POST';
							}else if(c == 'a'){
								rule.async = true;
							}else if(c == 'A'){
								rule.async = false;
							}else if(c == 't'){
								rule.dataType = 'text';
							}else if(c == 'j'){
								rule.dataType = 'json';
							}
						}
					}
					rule.url = rs[3];
					if(rs[5]){
						rule.params = rs[5];
					}
					if(rs[7]){
						rule.okcode = rs[7];
					}
					if(rs[9]){
						rule.errcode = rs[9];
					}
					if(rs[11]){
						rule.error = rs[11];
					}
					exprrules.push(rule);
					
				}else if((FormVerifier._startsWith(expr, 'len-max') || FormVerifier._startsWith(expr, 'chk-max') || FormVerifier._startsWith(expr, 'select-max'))
						&& (rs=(/^(len-max|chk-max|select-max)(:(\w+)?)?\[(\d+)\](\{(.+)\})?$/).exec(expr)) != null){
					var rule = {rtype:'input', type:'size'}, _type = rs[1];
					rule.max = parseInt(rs[4]);
					rule.error = rs[6] || ("len-max"==_type ? "最多"+rule.max+"个字符." : "最多选择"+rule.max+"项.");
					exprrules.push(rule);
					
				}else if((FormVerifier._startsWith(expr, 'len-min') || FormVerifier._startsWith(expr, 'chk-min') || FormVerifier._startsWith(expr, 'select-min'))
						&& (rs=(/^(len-min|chk-min|select-min)(:(\w+)?)?\[(\d+)\](\{(.+)\})?$/).exec(expr)) != null){
					var rule = {rtype:'input', type:'size'}, _type = rs[1];
					rule.min = parseInt(rs[4]);
					rule.error = rs[6] || ("len-min"==_type ? "最少"+rule.min+"个字符." : "最少选择"+rule.min+"项.");
					exprrules.push(rule);
					
				}else if((FormVerifier._startsWith(expr, 'len-eq') || FormVerifier._startsWith(expr, 'chk-eq') || FormVerifier._startsWith(expr, 'select-eq'))
						&& (rs=(/^(len-eq|chk-eq|select-eq)(:(\w+)?)?\[(\d+)\](\{(.+)\})?$/).exec(expr)) != null){
					var rule = {rtype:'input', type:'size'}, _type = rs[1];
					rule.min = rule.max = parseInt(rs[4]);
					rule.error = rs[6] || ("len-eq"==_type ? "必须由"+rule.min+"个字符组成." : "必须选择"+rule.min+"项.");
					exprrules.push(rule);
					
				}else if((FormVerifier._startsWith(expr, 'len') || FormVerifier._startsWith(expr, 'chk') || FormVerifier._startsWith(expr, 'select'))
						&& (rs=(/^(len|chk|select)(:(\w+)?)?\[(\d+),(\d+)\](\{(.+)\})?$/).exec(expr)) != null){
					var rule = {rtype:'input', type:'size'}, _type = rs[1];
					rule.min = parseInt(rs[4]);
					rule.max = parseInt(rs[5]);
					rule.error = rs[7] || ("len"==_type ? "必须由"+rule.min+"~"+rule.max+"个字符组成." : "必须选择"+rule.min+"~"+rule.max+"项.");
					exprrules.push(rule);
					
				}else if(FormVerifier._startsWith(expr, 'combox') && (rs=(/^combox(:(\w+)?)?\[(\w+)(,(\w+))?\](\{(.+)\})?$/).exec(expr)) != null){
					var rule = {rtype:'combox', valueid: null};
					rule.valueid = rs[5] || rs[3];
					rule.error = rs[7] || "请选择.";
					exprrules.push(rule);
					
				}else if(FormVerifier._startsWith(expr, 'num-fmt') && (rs=(/^num-fmt(:(\w+)?)?\[(\d+)(,(\d+))?(,([-+]))?\](\{(.+)\})?$/).exec(expr)) != null){
					var rule = {rtype:'regexp', ignoreCase: true, regexps:[]};
					FormVerifier._setRegexpRuleArgs(rule, rs[2]);
					rule.compare = 'or';
					var intlen = parseInt(rs[3]);
					var declen = 0;
					if(rs[5]){
						declen = parseInt(rs[5]);
					}
					if(intlen == 0){
						intlen = 1;
					}
					var sign = rs[7];
					var _regexp = '^';
					if(sign != "+"){
						_regexp = _regexp + '-?';
					}
					_regexp = _regexp + '\\d{1,'+intlen+'}';
					var _deferr='必须是数字，整数部分最多'+intlen+'位';
					if(declen > 0){
						_regexp = _regexp + '(\\.\\d{1,'+declen+'})?';
						_deferr = _deferr + '，小数最多'+declen+'位';
					}
					_regexp += '$';
					rule.regexps.push(_regexp);
					rule.error = rs[9] || _deferr;
					exprrules.push(rule);
					
				}else if(FormVerifier._startsWith(expr, 'num-max') && (rs=(/^num-max(:(\w+)?)?\[(-?\d+(\.\d+)?)\](\{(.+)\})?$/).exec(expr)) != null){
					var rule = {rtype:'input', type:'number'};
					rule.min = -2000000000;
					rule.max = parseFloat(rs[3]);
					rule.error = rs[6] || "值必须小于等于"+rule.max+".";
					exprrules.push(rule);
					
				}else if(FormVerifier._startsWith(expr, 'num-min') && (rs=(/^num-min(:(\w+)?)?\[(-?\d+(\.\d+)?)\](\{(.+)\})?$/).exec(expr)) != null){
					var rule = {rtype:'input', type:'number'};
					rule.min = parseFloat(rs[3]);
					rule.max = 2000000000;
					rule.error = rs[6] || "值必须大于等于"+rule.min+".";
					exprrules.push(rule);
					
				}else if(FormVerifier._startsWith(expr, 'numrange') && (rs=(/^numrange(:(\w+)?)?\[(.+)\](\{(.+)\})?$/).exec(expr)) != null){
					var rule = {rtype:'numrange', type: 'number', compare: 'or', exprs:[]}, args = rs[2];
					if(args){
						for(var i=0; i<args.length; i++){
							var c = args.charAt(i);
							if(c == 'a'){
								rule.compare = 'and';
							}else if(c == 'o'){
								rule.compare = 'or';
							}else if(c == 'n'){
								rule.type = 'number';
							}else if(c == 'l'){
								rule.type = 'length';
							}
						}
					}
					rule.args.push(rs[3]);
					rule.error = rs[5] || "值无效.";
					exprrules.push(rule);
					
				}else if(FormVerifier._startsWith(expr, 'num') && (rs=(/^num(:(\w+)?)?\[(-?\d+(\.\d+)?),(-?\d+(\.\d+)?)\](\{(.+)\})?$/).exec(expr)) != null){
					var rule = {rtype:'input', type:'number'};
					rule.min = parseFloat(rs[3]);
					rule.max = parseFloat(rs[5]);
					rule.error = rs[8] || "值必须在"+rule.min+"~"+rule.max+"之间.";
					exprrules.push(rule);
					
				}else if(FormVerifier._startsWith(expr, 'any') && (rs=(/^any(:(\w+)?)?\[(.+?)(,(.*?))?(,(\d*))?\](\{(.+)\})?$/).exec(expr)) != null){
					var rule = {rtype:'anyitem', min:1};
					rule.dest = (rs[5] || rs[3] || '').split(/[,;]/g);
					if(rs[7]){
						rule.min = parseInt(rs[7]) || 0;
					}
					rule.error = rs[9] || "不能为空.";
					exprrules.push(rule);
					
				}else if(FormVerifier._startsWith(expr, 'compare') && (rs=(/^compare(:(\w+)?)?\[(\w+)(,(\w+))?\](\{(.+)\})?$/).exec(expr)) != null){
					var rule = {rtype:'compare', type:'string', dest: null, operateor:'gt'}, args = rs[2];
					if(args){
						args = args.replace(/[_]/g, "__");
						var argsreg = /[0-9A-Z]|_[0-9A-Z]+_/ig, argsrs;
						while((argsrs=argsreg.exec(args)) != null){
							var arg = argsrs[0];
							if(arg == 'n'){
								rule.type = "number";
							}else if(arg == 'd'){
								rule.type = "date";
							}else if(arg == 't'){
								rule.type = "datetime";
							}else if(arg == 's'){
								rule.type = "string";
							}else if(arg=='_eq_' || arg=='_ne_' || arg=='_gt_' || arg=='_ge_' || arg=='_lt_' || arg=='_le_'){
								rule.operateor = arg.substring(1, 3);
							}
						}
					}
					rule.dest = rs[5] || rs[3];
					rule.error = rs[7] || "输入错误.";
					exprrules.push(rule);
					
				}else if(FormVerifier._startsWith(expr, 'notempty') && (rs=(/^notempty(:(\w+)?)?(\{(.+)\})?$/).exec(expr)) != null){
					var rule = {rtype:'input', type:'size', min: 1};
					rule.error = rs[4] || "不能为空.";
					exprrules.push(rule);
					
				}else{
					if(regData.regs && (rs=(/^(\w+)(:(\w+)?)?(\{(.+)\})?/i).exec(expr)) != null){
						var name = rs[1], error = rs[5];
						var regex = regData.regs[name];
						if(regex != null){
							var rule = {rtype:'regexp', ignoreCase: true, regexps:[]};
							FormVerifier._setRegexpRuleArgs(rule, rs[3]);
							rule.compare = 'or';
							rule.regexps.push(regex);
							rule.error = error || regData.errs[name] || "输入格式错误.";
							exprrules.push(rule);
						}
					}
				}
			}
			if(exprrules.length){
				if(item.rules.length){
					exprrules = exprrules.concat(item.rules);
				}
				item.rules = exprrules;
			}
		}//for-i
		return items;
	}//parseRulesExpr
	
};

//验证表单
function verifyForm(formID, settings, callback){
	var defaultOptions = {
			formID: null,
			submitID: "submit1",
			theme: "Default",
			mode: "AutoTip",
			action: null,//form action，默认取表单的action属性，可指定替换默认值
			item_settings: null,//验证表单项的公共扩展参数
			autoinit: true,//字段初始化表单验证配置，如果onBeforeInit的返回值!==false忽略该参数
			localRule: false,//使用本地规则 - 不从服务器加载
			localRules: null,//定义本地规则 //[{id:"id", tips:"", empty:false, settings:{}, expr:[], rules:[]}]
			onBeforeInit: null,//在此方法中进行表单验证初始化
			onInited: null//在此方法中进行补充验证
	};
	if(typeof settings == 'function'){
		callback = settings;
		settings = undefined;
	}
	if(typeof formID == 'object'){
		settings = formID;
		formID = settings.formID;
	}
	settings = $.extend({}, defaultOptions, settings||{});
	if(!settings.action && formID){
		var form = $('#'+formID);
		var vfaction = $('#_verifier_action', form).val();
		if(vfaction){
			settings.action = vfaction;
		}else{
			settings.action = FormVerifier.getFormAction(formID);
		}
	}
	
	function _verifyLocal(){
		jQuery.ajax({
			type: "GET",
			dataType: "json",
			url: FormVerifier.path+"/public/getFormVerifier.json",
			data:{type : "getregexps"},
			success: function(regData){
				if(typeof(regData)=='string'){
					regData = jQuery.parseJSON(regData);
	    		}
				if(typeof settings.onBeforeInit == 'function'){
					var inited = settings.onBeforeInit(regData.skin);
					if(inited === false){
						$.formValidator.initConfig({formID: formID, theme: (regData.skin || settings.theme), mode: settings.mode, onError:function(){
							UiUtil.unlockButton(settings.submitID);
						}});
					}
				}else if(settings.autoinit && formID){
					$.formValidator.initConfig({formID: formID, theme: (regData.skin || settings.theme), mode: settings.mode, onError:function(){
						UiUtil.unlockButton(settings.submitID);
					}});
				}
				var rules = FormVerifier.parseRulesExpr(regData, settings.localRules || []);
				var vmap = FormVerifier.doVerify({items: rules}, settings);
				if(typeof settings.onInited == 'function'){
					settings.onInited(true, vmap);
				}
				if(typeof callback == 'function'){
					callback(true, vmap);
				}
			},
			error: function(){
				if(typeof settings.onInited == 'function'){
					settings.onInited(false);
				}
				if(typeof callback == 'function'){
					callback(false);
				}
			}
		});
	}
	
	if(settings.localRule === true){
		_verifyLocal();
	}else{
		jQuery.ajax({
			type: "GET",
			dataType: "json",
			url: FormVerifier.path+"/public/getFormVerifier.json",
			data:{action : settings.action},
			success: function(data){
				if(typeof(data)=='string'){
					data = jQuery.parseJSON(data);
	    		}
				if(!data || !data.items){
					//如果服务器上没有定义验证规则且存在本地规则则使用本地规则验证
					if(settings.localRules && settings.localRules.length){
						_verifyLocal();
					}else{
						if(typeof settings.onInited == 'function'){
							settings.onInited(false);
						}
						if(typeof callback == 'function'){
							callback(false);
						}
					}
					return;
				}
				if(typeof settings.onBeforeInit == 'function'){
					var inited = settings.onBeforeInit(data.skin || settings.theme);
					if(inited === false){
						$.formValidator.initConfig({formID: formID, theme: (data.skin || settings.theme), mode: settings.mode, onError:function(){
							UiUtil.unlockButton(settings.submitID);
						}});
					}
				}else if(settings.autoinit && formID){
					$.formValidator.initConfig({formID: formID, theme: (data.skin || settings.theme), mode: settings.mode, onError:function(){
						UiUtil.unlockButton(settings.submitID);
					}});
				}
				var vmap = FormVerifier.doVerify(data, settings);
				if(typeof settings.onInited == 'function'){
					settings.onInited(true, vmap);
				}
				if(typeof callback == 'function'){
					callback(true, vmap);
				}
			},
			error: function(){
				if(typeof settings.onInited == 'function'){
					settings.onInited(false);
				}
				if(typeof callback == 'function'){
					callback(false);
				}
			}
		});
	}
	
}


